#include "ir_drv.h"

/**
 * @desc  : GPIO初始化
 * @date  : 2025-04-02
 * @author: AnRui
 * @note  :
 */
static void GpioInit(void) {
    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_init(GPIOC, GPIO_MODE_IPU, GPIO_OSPEED_10MHZ, GPIO_PIN_6);
}

/**
 * @desc  : 定时器初始化
 * @date  : 2025-04-02
 * @author: AnRui
 * @note  : timer7 通道0 上升沿捕获
 */
static void Timer7Init() {
    /* 使能定时器时钟；*/
    rcu_periph_clock_enable(RCU_TIMER7);
    /* 复位定时器；*/
    timer_deinit(TIMER7);
    timer_parameter_struct timerInitPara;
    timer_struct_para_init(&timerInitPara);
    /* 设置预分频器值；*/
    timerInitPara.prescaler = TIMER7_PRESCALER - 1;     // 输入给计数器的时钟频率为1Mhz，周期1us
    /* 设置自动重装载值；*/
    timerInitPara.period = TIMER7_PERIOD;
    timer_init(TIMER7, &timerInitPara);
    timer_ic_parameter_struct icInitPara;
    timer_channel_input_struct_para_init(&icInitPara);
    /* 设置上升沿/下降沿捕获；*/
    icInitPara.icpolarity = TIMER_IC_POLARITY_FALLING;
    /* 设置输入通道；*/
    icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_input_capture_config(TIMER7, TIMER_CH_0, &icInitPara);
    /* 使能定时器的捕获中断；*/
    timer_interrupt_flag_clear(TIMER7, TIMER_INT_FLAG_CH0);
    timer_interrupt_enable(TIMER7, TIMER_INT_CH0);
    /* 使能定时器中断和优先级；*/
    nvic_irq_enable(TIMER7_Channel_IRQn, 0, 0);
    /* 使能定时器；*/
    timer_enable(TIMER7);
}

/**
***********************************************************
* @brief 红外接收硬件初始化函数
* @param
* @return
***********************************************************
*/
void IrDrvInit(void) {
    GpioInit();
    Timer7Init();
}

void ParseIrFrame(uint32_t value);

/**
 * @desc  : TIMER7中断回调函数
 * @date  : 2025-04-02
 * @author: AnRui
 * @note  :
 */
void TIMER7_Channel_IRQHandler(void) {
    uint32_t icValue;
    if (timer_interrupt_flag_get(TIMER7, TIMER_INT_FLAG_CH0) == SET) {
        timer_interrupt_flag_clear(TIMER7, TIMER_INT_FLAG_CH0);
        icValue = timer_channel_capture_value_register_read(TIMER7, TIMER_CH_0) + 1;
        timer_counter_value_config(TIMER7, 0);
        ParseIrFrame(icValue);
    }
}


static uint8_t g_irCode[4] = { 0 };
static bool g_irCodeFlag = false;

/**
 * @desc  :
 * @date  : 2025-04-02
 * @author: AnRui
 * @param : tickNum - {参数说明}:
 * @note  : 如果第一次下降沿就满足引导码格式呢？
 */
static void ParseIrFrame(uint32_t tickNum) {
    static bool s_headFlag = false;
    static uint8_t s_index = 0; //32位接收数据 index表示接收到第几位了
    // 判断引导码
    if (tickNum > TICK_HEAD_MIN && tickNum < TICK_HEAD_MAX) {
        s_headFlag = true;
        return;
    }
    if (!s_headFlag) { return; }

    // 接收数据
    if (tickNum > TICK_1_MIN && tickNum < TICK_1_MAX) {
        g_irCode[s_index / 8] >>= 1;
        g_irCode[s_index / 8] |= 0x80;
        s_index++;
    }
    if (tickNum > TICK_0_MIN && tickNum < TICK_0_MAX) {
        g_irCode[s_index / 8] >>= 1;
        s_index++;
    }

    // 接收完校验
    if (s_index == 32) {
        if ((g_irCode[2] & g_irCode[3]) == 0) {
            g_irCodeFlag = true;
        } else {
            g_irCodeFlag = false;
        }
        s_headFlag = false;
        s_index = 0;
    }
}

/**
 * @desc  : 获取码值
 * @date  : 2025-04-02
 * @author: AnRui
 * @param : code - {参数说明}:
 * @return: true
 * @return: false
 * @note  :
 */
bool GetIrCode(uint8_t* code) {
    if (!g_irCodeFlag) {
        return false;
    }
    *code = g_irCode[2];
    g_irCodeFlag = false;
    return true;
}
